// ----------------------------------------------------------------------------
// stl_unit_test.cpp
// ----------------------------------------------------------------------------
#include <fw/base/core/macros.h>
#if defined(FW_ENABLE_UNIT_TEST)
    #include <fw/base/core/debugconsole.h>
    #include <gtest/gtest.h>
    #include <fw/base/stl/stl_algorithm.h>
    #include <fw/base/stl/stl_vector.h>
    #include <fw/base/stl/stl_array.h>
    #include <fw/base/stl/stl_string.h>
    #include <fw/base/stl/stl_set.h>
    #include <fw/base/stl/stl_map.h>
    #include <fw/base/stl/stl_list.h>
    #include <fw/base/stl/stl_hash_map.h>
#if defined(FW_USE_EASTL)
    // 固定長コンテナ.
    #include <fw/base/stl/fixed_hash_map.h>
    #include <fw/base/stl/fixed_list.h>
    #include <fw/base/stl/fixed_map.h>
    #include <fw/base/stl/fixed_set.h>
    #include <fw/base/stl/fixed_string.h>
    #include <fw/base/stl/fixed_vector.h>
#endif

    // stl::vector
    TEST(stl, vector)
    {
        stl::vector<int> testIntArray; testIntArray.reserve(24);
        testIntArray.push_back(1234);
        testIntArray.push_back(5678);
        testIntArray.push_back(5963);
        
        ASSERT_EQ(testIntArray[0], 1234);
        ASSERT_EQ(testIntArray[1], 5678);
        ASSERT_EQ(testIntArray[2], 5963);
        
        int counter = 0;
        for(auto it=testIntArray.begin(); it!=testIntArray.end(); ++it, ++counter)
        {
        }
        ASSERT_EQ(testIntArray.size(), counter);
        
        stl::vector<int>().swap(testIntArray);
        ASSERT_EQ(testIntArray.size(), 0);
    }

    // std::array
    TEST(stl, array)
    {
        static const int kNumIndex = 3;
        std::array<int, kNumIndex> indexArray;
        indexArray.fill(0);
        
        ASSERT_EQ(indexArray.size(), kNumIndex);
        
        auto copyArray = indexArray;
        
        ASSERT_EQ(copyArray, indexArray);
        
        copyArray[0] = 3;
        copyArray[1] = 2;
        copyArray[2] = 1;
        
        stl::swap(copyArray, indexArray); // compare whole array indices.
        
        ASSERT_EQ(copyArray[0],  0);
        ASSERT_EQ(copyArray[1],  0);
        ASSERT_EQ(copyArray[2],  0);
        ASSERT_EQ(indexArray[0], 3);
        ASSERT_EQ(indexArray[1], 2);
        ASSERT_EQ(indexArray[2], 1);
        
        auto find0 = stl::find(indexArray.begin(), indexArray.end(), 2);
        ASSERT_NE(find0, indexArray.end());
        
        auto find1 = stl::find(copyArray.begin(),  copyArray.end(),  2);
        ASSERT_EQ(find1, copyArray.end());
    }

#if defined(FW_USE_EASTL)
    // カスタムアロケータが設定可能かどうかを判定するためのダミーのアロケータ.
    class EastlAllocator
    {
        const char*     m_name;
    public:
        EastlAllocator(const char* name="EASTL")
        : m_name(name)
        {
        }
        
        EastlAllocator(const EastlAllocator& other)
        : m_name(other.m_name)
        {
        }
        
        EastlAllocator(const EastlAllocator& other, const char* name)
        : m_name(name)
        {
        }
        
        
        const char*     GetName() const
        {
            return m_name;
        }
        
        void            SetName(const char* name)
        {
            m_name = name;
        }
        
    }; //class EastlAllocator

    bool operator==(const EastlAllocator& a, const EastlAllocator& b)
    {
        return !(strcmp(a.GetName(), b.GetName()));
    }

    bool operator!=(const EastlAllocator& a, const EastlAllocator& b)
    {
        return !(a==b);
    }

    // eastl/vector で、メモリアロケータを入れ替えたケースのテスト.
    TEST(stl, eastl_vector)
    {
        
    }

#endif

//	{
//		stl::string testString("Hello, STL.");
//		FW_PRINTF("testString = [%s]:length[%d]:capacity[%d]\n",
//			  testString.c_str(),
//			  testString.length(),
//			  testString.capacity());
//	}


#endif // FW_ENABLE_UNIT_TEST

void STL_UNIT_TEST()
{
}
